<?php
/**************************************************************************
	PHP Api Lib
	Copyright (C) 2007  Kw4h, 2009 Clinton Weiss

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

if (!defined('SMF'))
{
	require(dirname(__FILE__) . '/../SSI.php');
}

class EsamEveApi {
	private $apikey = null;
	private $userid = null;
	private $charid = null;
	private $corpid = null;
	private $name		= null;
	private $apisite = "api.eve-online.com";
	private $cachetime = 60;
	// private $timeformat = "Y-n-d H:i:s";
	public $debug = true;
	private $msg = array();
	private $usecache = true;

	function getCacheDir()
	{
		return sys_get_temp_dir() . '/esam_cache/';
	}

	public function setCredentials($userid, $apikey, $charid = null, $corpid = null)
	{
		if (!empty($userid) && !empty($apikey) && is_numeric($userid))
		{
			$this->userid = $userid;
			$this->apikey = $apikey;
		}

		if (!empty($charid))
		{
			$this->charid = $charid;
		}

        if (!empty($corpid))
		{
			$this->corpid = $corpid;
		}
	}

	public function setName($charOrCorpName)
	{
		$this->name = $charOrCorpName;
	}

	public function debug($bool)
	{
		if (is_bool($bool))
			$this->debug = $bool;
	}

	public function cache($bool)
	{
		if (is_bool($bool))
			$this->usecache = $bool;
	}

	// add error message - both params are strings and are formatted as: "$type: $message"
	private function addMsg($type, $message)
	{
		if (!empty($type) && !empty($message))
		{
			$index = count($this->msg);

			$this->msg[$index]['type'] = $type;
			$this->msg[$index]['msg'] = $message;
		}
	}
    public function isError()
    {
        if (count($this->msg) > 0) return true;
        return false;
    }

	/**********************
		Retrieve an XML File
		$path	path relative to the $apisite url
		$params	array of paramaters (exclude apikey and userid, and charid)
				$params['characterID'] = 123456789;
	***********************/
	public function retrieveXml($path, $params = null)
	{
		if (!empty($path))
		{
			$params = array();
			if ($this->userid != null && $this->apikey != null)
			{
				$params['userID'] = $this->userid;
				$params['apiKey'] = $this->apikey;
			}

			if ($this->name != null)
			{
				$params['name'] = $this->name;
			}

			if ($this->charid != null)
			{
				$params['characterID'] = $this->charid;
			}

			if ($this->corpid != null)
			{
				$params['corporationID'] = $this->corpid;
			}

			if ($this->usecache && $this->isCached($path))
			{
				return $this->loadCache($path);
			}
			else // continue when not cached
			{
				// poststring
				if (count($params) > 0)
				{
					$poststring = "";
					if (isset($params['name']))
					{
						$poststring = "names=" . $params["name"];
					} else
					{
						if (isset($params['userID']))
						{
								$poststring = "userID=".$params['userID']."&apiKey=".$params['apiKey'];
						}
						if (isset($params['characterID'])) $poststring .= "&characterID=".$params['characterID'];
						if (isset($params['corporationID'])) $poststring .= "corporationID=".$params['corporationID'];
					}
        } else
				{
					$poststring = "";
				}

				// open connection to the api
				$fp = fsockopen($this->apisite, 80);

				if (!$fp)
				{
					if ($this->debug)
						$this->addMsg("Error", "Could not connect to API URL");
				}
				else
				{
					// request the xml
					fputs ($fp, "POST " . $path . " HTTP/1.0\r\n");
					fputs ($fp, "Host: " . $this->apisite . "\r\n");
					fputs ($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
					fputs ($fp, "User-Agent: PHPApi\r\n");
					fputs ($fp, "Content-Length: " . strlen($poststring) . "\r\n");
					fputs ($fp, "Connection: close\r\n\r\n");
					if (strlen($poststring) > 0)
						fputs ($fp, $poststring."\r\n");

					// retrieve contents
					$contents = "";
					while (!feof($fp))
					{
						$contents .= fgets($fp);
					}

					// close connection
					fclose($fp);

					$start = strpos($contents, "\r\n\r\n");
					if ($start !== FALSE)
					{
						$contents = substr($contents, $start + strlen("\r\n\r\n"));
						if (strpos($contents, "Server is too busy"))
						{
							fatal_error("API server is currently not taking requests.", false);
						}

						// check if there's an error or not
						$xml = new SimpleXMLElement($contents);

						$error = (string) $xml->error;
						if (!empty($error))
						{
							if ($this->debug)
							{
								$this->addMsg("Api", $error);
							}

							return null;
						}

						// Store the contents
						$this->store($contents, $this->getCacheFile($path));
						return $contents;
					}

					if ($this->debug)
					{
						$this->addMsg("Error", "Could not parse contents");
					}

					return null;
				}
			}
		}
		else
		{
			$this->addMsg("Error", "Path is empty");
		}

		return null;
	}

	private function store($contents, $path)
	{
		if (!file_exists(dirname($path)))
		{
			mkdir(dirname($path), 0777, true);
		}

		$fp = fopen($path, "w");

		if ($fp)
		{
			fwrite($fp, $contents);
			fclose($fp);
			chmod($path, 0600);
		}
		else
		{
			if ($this->debug)
			{
				$this->addMsg("Error", "Could not open file for writing: " . $path);
			}
		}

	}

	private function getCacheFile($path)
	{
		$adjustedpath = "";

		if (!empty($this->userid))
		{
      if (!empty($this->charid) && !empty($this->apikey))
      {
        $adjustedpath = $this->userid . '/' . $this->charid . '/' . $this->apikey . $path;
      }
			else if (!empty($this->charid))
			{
				$adjustedpath = $this->userid . '/' . $this->charid . $path;
			}
			else
			{
				$adjustedpath = $this->userid . $path;
			}
		}
		else if (!empty($this->corpid))
		{
			$adjustedpath = $this->corpid . $path;
		} else if (!empty($this->name))
		{
			$adjustedpath = $this->name . $path;
		}
		else
		{
			$adjustedpath = $path;
		}

		$realpath = str_replace(" ", "_", $adjustedpath);
		$realpath = str_replace("/", "_", $adjustedpath);
		return $this->getCacheDir() . '/' . $realpath;
	}

	private function loadCache($path)
	{
		// its cached, open it and use it
		$file = $this->getCacheFile($path);

		$fp = fopen($file, "r");
		if ($fp)
		{
			$contents = fread($fp, filesize($file));
			fclose($fp);
		}
		else
		{
			if ($this->debug)
			{
				//$this->addMsg("Error", "Could not open file for reading: " . $path);
			}
		}

		return $contents;
	}

	// checking if the cache expired or not based on TQ time
	private function isCached($path)
	{
		$cachefile = $this->getCacheFile($path);
		if (file_exists($cachefile))
		{
			$fp = fopen($cachefile, "r");

			if ($fp)
			{
				$contents = fread($fp, filesize($cachefile));
				fclose($fp);

				try
				{
				// check cache
					$xml = new SimpleXMLElement($contents);
				} catch (Exception $ex)
				{
					return false;
				}
				

				$cachetime = (string) $xml->cachedUntil;
				$time = strtotime($cachetime);

				// get GMT time
				$timenow = time();
				$now = $timenow - date('Z', $timenow);

				// if now is an hour ahead of the cached time, pretend this file is not cached
				$minutes = $this->cachetime * 60;
				if ($now >= $time + $minutes)
				{
					return false;
				}

				return true;
			}
			else
			{
				if ($this->debug)
				{
					$this->addMsg("Error", "Could not open file for writing: " . $path);
				}
			}
		}
		else
		{
			if ($this->debug)
			{
				//$this->addMsg("Error", "File does not exist: " . $cachefile);
			}
		}
	}

	public function printErrors()
	{
		foreach ($this->msg as $msg)
		{
			echo ("<b>" . $msg['type'] . "</b>: " . $msg['msg'] . "</br>\n");
		}
	}

	public function getErrors()
	{
		$text = '';
		foreach ($this->msg as $msg)
		{
			$text = $text .  ($msg['type'] . ": " . $msg['msg']);
		}
		return $text;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Functions to retrieve data
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public function getCharacterSheet()
	{
		$contents = $this->retrieveXml("/char/CharacterSheet.xml.aspx");

		return $contents;
	}

	public function getCharacters()
	{
		$contents = $this->retrieveXml("/account/Characters.xml.aspx");

		return $contents;
	}

	public function getRefTypes()
	{
		$contents = $this->retrieveXml("/eve/RefTypes.xml.aspx");

		return $contents;
	}

    public function getAllianceList()
    {
        $contents = $this->retrieveXml("/eve/AllianceList.xml.aspx");

        return $contents;
    }

    public function getCorporationInfo()
    {
        $contents = $this->retrieveXml("/corp/CorporationSheet.xml.aspx");
        return $contents;
    }

		public function getCharacterOrCorporationInfo()
		{
			return $this->retrieveXml("/eve/CharacterID.xml.aspx");
		}

		public function getCharacterName($character_id)
		{
			return $this->retrieveXml("/eve/CharacterName.xml.aspx?ids=$character_id");
		}

}?>
